package com.xhsj.user.cram.service;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xhsj.user.cram.dto.*;
import com.xhsj.user.cram.entity.TbComputerRoomAccessApply;
import com.xhsj.user.cram.entity.TbComputerRoomAccessPersonnel;
import com.xhsj.user.cram.mapper.TbComputerRoomAccessApplyMapper;
import com.xhsj.user.cram.mapper.TbComputerRoomAccessPersonnelMapper;
import com.xhsj.user.cram.vo.FindComputerRoomAccessDetailedVo;
import com.xhsj.user.cram.vo.FindComputerRoomAccessHiTaskVo;
import com.xhsj.user.cram.vo.FindComputerRoomAccessRunTaskVo;
import com.xhsj.user.generalprocess.entity.TbPamGeneralProcessHiTask;
import com.xhsj.user.generalprocess.mapper.TbPamGeneralNodeMapper;
import com.xhsj.user.generalprocess.mapper.TbPamGeneralProcessTaskMapper;
import com.xhsj.user.generalprocess.service.TbPamGeneralProcessTaskService;
import com.xhsj.user.generalprocess.vo.GeneralAuditHistoryVo;
import com.xhsj.user.generalprocess.vo.GeneralAuditVo;
import com.xhsj.user.generalprocess.vo.GeneralHiTaskVo;
import com.xhsj.user.generalprocess.vo.GeneralRunTaskVo;
import com.xhsj.user.hr.base.BaseParam;
import com.xhsj.user.hr.base.BaseService;
import com.xhsj.user.hr.system.mapper.TbGlobalUserMapper;
import com.xhsj.user.pms.patent.vo.FindHiTaskVo;
import com.xhsj.user.pms.patent.vo.FindRunTaskVo;
import com.xhsj.user.pms.patent.vo.ProcessNodeVo;
import com.xhsj.user.properties.RoleKeyNameProperites;
import com.xhsj.user.utils.IdGen;
import com.xhsj.user.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.io.Serializable;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotBlank;

/**
 * <p>
 * 机房出入申请 服务实现类
 * </p>
 *
 * @author liuqinghua
 * @since Apr 19, 2021 7:26:32 AM
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbComputerRoomAccessApply")
public class TbComputerRoomAccessApplyService extends BaseService<TbComputerRoomAccessApplyMapper, TbComputerRoomAccessApply> {
    @Autowired
    private TbComputerRoomAccessApplyMapper dao;

    @Autowired
    private TbComputerRoomAccessPersonnelService tbComputerRoomAccessPersonnelService;

    @Autowired
    private TbGlobalUserMapper userMapper;

    @Autowired
    private TbPamGeneralProcessTaskService tbPamGeneralProcessTaskService;

    @Autowired
    private RoleKeyNameProperites roleKeyNameProperites;

    @Autowired
    private TbPamGeneralNodeMapper tbPamGeneralNodeMapper;

    @Autowired
    private TbPamGeneralProcessTaskMapper tbPamGeneralProcessTaskMapper;
	/**
	 * 保存
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    @Override
    //@CacheEvict(cacheNames="TbComputerRoomAccessApply", allEntries=true)
    public boolean save(TbComputerRoomAccessApply entity) {
        return super.save(entity);
    }

	/**
	 * 通过id获取数据
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    @Override
    //@Cacheable(key = "#id",sync = true)
    public TbComputerRoomAccessApply getById(Serializable id) {
        return super.getById(id);
    }

	/**
	 * 通过id删除数据
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    @Override
    //@CacheEvict(cacheNames="TbComputerRoomAccessApply", allEntries=true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

	/**
	 * 批量删除数据
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    //@CacheEvict(cacheNames="SysDict", allEntries=true)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return super.removeByIds(idList);
    }

	/**
	 * 分页查询数据
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    //@Cacheable(key = "#data",sync = true)
    public IPage<TbComputerRoomAccessApply> selectPage(Map<String,Object> data) {
        int currentPage=1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage=(Integer) data.get("page");
        }
        int pageSize=20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize=(Integer) data.get("size");
        }

        TbComputerRoomAccessApply entity = JSON.parseObject(JSON.toJSONString(data), TbComputerRoomAccessApply.class);
        Page<TbComputerRoomAccessApply> page = new Page(currentPage,pageSize);
        QueryWrapper<TbComputerRoomAccessApply> wrapper = new QueryWrapper(entity);
        return super.selectPage(page, wrapper);
    }

	/**
	 * 查询所有数据
	 * @author liuqinghua
	 * @date Apr 19, 2021 7:26:32 AM
	 */
    @Override
    //@Cacheable(value = "TbComputerRoomAccessApply",sync = true)
    public List<TbComputerRoomAccessApply> selectAll() {
        return super.selectAll();
    }


    /**
     * @Description:  机房出入-部门提交需求保存
     * @Param: com.xhsj.user.cram.dto.ComputerRoomAccessApplyStartDto
     * @Author: liuqinghua
     * @Date: 2021/4/19
     */
    public void computerRoomAccessDeptApplySave(ComputerRoomAccessApplySaveDto data) throws Exception {
        // 保存数据到申请表中
        TbComputerRoomAccessApply tbComputerRoomAccessApply=new TbComputerRoomAccessApply();
        BeanUtils.copyProperties(data,tbComputerRoomAccessApply);
        tbComputerRoomAccessApply.setNodeId(new Long(1));
        tbComputerRoomAccessApply.setNodeName("部门机房出入申请");
        if(!super.save(tbComputerRoomAccessApply))
            throw new Exception("保存数据到申请表中异常");
        // 删除人员
        tbComputerRoomAccessPersonnelService.deleteByDataId(tbComputerRoomAccessApply.getId());
        // 保存数据到人员表中
        List<ComputerRoomAccessPersonnelSaveDto> personnelList = data.getPersonnelList();
        for (ComputerRoomAccessPersonnelSaveDto computerRoomAccessPersonnelSaveDto : personnelList) {
            TbComputerRoomAccessPersonnel tbComputerRoomAccessPersonnel=new TbComputerRoomAccessPersonnel();
            BeanUtils.copyProperties(computerRoomAccessPersonnelSaveDto,tbComputerRoomAccessPersonnel);
            tbComputerRoomAccessPersonnel.setDataId(tbComputerRoomAccessApply.getId());
            if(!tbComputerRoomAccessPersonnelService.save(tbComputerRoomAccessPersonnel))
                throw new Exception("保存数据到人员表中异常");
        }

        // 判断当前用户是网络信息安全工程师流程-综合管理部
        List<Long> roleIds = userMapper.getRoleIdsByUserId(UserUtils.getLoginAppUser().getUserId());
        if(roleIds.contains(new Long(166))){
            ComputerRoomAccessApplyExamineDto computerRoomAccessApplyExamineDto = new ComputerRoomAccessApplyExamineDto();
            computerRoomAccessApplyExamineDto.setStatus(0);
            computerRoomAccessApplyExamineDto.setId(tbComputerRoomAccessApply.getId());
            this.computerRoomAccessApplyExamine_2(computerRoomAccessApplyExamineDto);
        }
    }

    /**
     * @Description: 待审核数据
     * @Param:  com.xhsj.user.hr.base.data
     * @Author: liuqinghua
     * @Date: 2021/4/19
     */
    public IPage<FindComputerRoomAccessRunTaskVo> findComputerRoomAccessRunTask(BaseParamDto baseParam) throws Exception {
        // 查询正在执行中任务
        GeneralAuditVo generalAuditVo = new GeneralAuditVo();
        generalAuditVo.setPage(baseParam.getPage());
        generalAuditVo.setSize(baseParam.getSize());
        generalAuditVo.setUserIds(Arrays.asList(UserUtils.getLoginAppUser().getUserId()));
        List<Long> roleIds = userMapper.getRoleIdsByUserId(UserUtils.getLoginAppUser().getUserId());
        generalAuditVo.setRoleIds(roleIds);
        this.fillParams(generalAuditVo);
        if(roleIds.contains(new Long(166))){
            // 网络信息安全工程师待审核列表
            Page<FindComputerRoomAccessRunTaskVo> page = new Page<>(generalAuditVo.getPage(), generalAuditVo.getSize());
           return dao.findComputerRoomAccessRunTask(page,generalAuditVo,baseParam);
        }else {
            IPage<GeneralRunTaskVo> iPage = tbPamGeneralProcessTaskService.findRunTask(generalAuditVo);
            List<GeneralRunTaskVo> runTask = iPage.getRecords();

            if (runTask != null && runTask.size() > 0) {
                List<Long> dataIds = runTask.stream().map(generalHiTaskVo -> generalHiTaskVo.getDataId()).collect(Collectors.toList());
                List<FindComputerRoomAccessRunTaskVo> list = dao.findComputerRoomAccessRunTaskByDataIds(dataIds);
                for (FindComputerRoomAccessRunTaskVo findRunTaskVo : list) {
                    for (GeneralRunTaskVo generalRunTaskVo : runTask) {
                        if (findRunTaskVo.getDataId().equals(generalRunTaskVo.getDataId())) {
                            // 填充数据
                            findRunTaskVo.setProcessTaskId(generalRunTaskVo.getProcessTaskId());

                            break;
                        }
                    }
                }
                IPage<FindComputerRoomAccessRunTaskVo> resultPage = new Page<>();
                resultPage.setRecords(list);
                resultPage.setPages(iPage.getPages());
                resultPage.setTotal(iPage.getTotal());
                return resultPage;
            }
            IPage<FindComputerRoomAccessRunTaskVo> resultPage = new Page<>();
            return resultPage;

        }

    }

    /**
     * 填充参数
     *
     * @author 苏小林
     * @date 2021/1/22 17:48
     * @param: generalAuditVo
     */
    private void fillParams(GeneralAuditVo generalAuditVo) {
        generalAuditVo.setProcessType("in_out_apply");
        generalAuditVo.setNodeTableName("tb_pam_general_node");
        generalAuditVo.setTaskTableName("tb_pam_general_process_task");
        generalAuditVo.setHiTaskTableName("tb_pam_general_process_hi_task");
        generalAuditVo.setOpinionFileTableName("tb_pam_general_opinion_file");

    }

    /**
     * @Description: 我的申请数据
     * @Param:  com.xhsj.user.hr.base.data
     * @Author: liuqinghua
     * @Date: 2021/4/20
     */
    public IPage<FindComputerRoomAccessRunTaskVo> findMyComputerRoomAccessApply(BaseParamDto data) {
        Page page=new Page(data.getPage(),data.getSize());
        data.setCreateBy(UserUtils.getLoginAppUser().getUserId());
        return dao.findMyComputerRoomAccessApply(page,data);
    }

    /**
     * @Description: 审批页面展示数据
     * @Param:  com.xhsj.user.hr.base.data
     * @Author: liuqinghua
     * @Date: 2021/4/20
     */
    public FindComputerRoomAccessDetailedVo findComputerRoomAccessDetailed(Long dataId) {
        return dao.findComputerRoomAccessDetailed(dataId);
    }

    /**
     * @Description:  机房出入流程-网络信息安全工程师处理
     * @Param: com.xhsj.user.cram.dto.ComputerRoomAccessApplySaveDto
     * @Author: liuqinghua
     * @Date: 2021/4/19
     */
    public void computerRoomAccessApplyExamine_2(ComputerRoomAccessApplyExamineDto data) throws Exception {
        // 组装审核数据
        GeneralAuditVo generalAuditVo = new GeneralAuditVo();
        BeanUtils.copyProperties(data,generalAuditVo);
        generalAuditVo.setDataId(data.getId());
        this.fillParams(generalAuditVo);
        // 流程处理-通过-综合管理部
        if(data.getStatus()==0){
            Long roleId = userMapper.getRoleIdByRoleKeyName(roleKeyNameProperites.getIntegratedManager());
            generalAuditVo.setRoleIds(Arrays.asList(roleId));
        }
        TbComputerRoomAccessApply tbComputerRoomAccessApply=new TbComputerRoomAccessApply();
        tbPamGeneralProcessTaskService.startProcess(generalAuditVo, generalCallableVo -> {
            tbComputerRoomAccessApply.setNodeId(generalCallableVo.getNodeId());
            tbComputerRoomAccessApply.setNodeName(generalCallableVo.getNodeName());
        });
        if (data.getStatus()==1) {
            tbComputerRoomAccessApply.setNodeId(new Long(-1));
            tbComputerRoomAccessApply.setNodeName("部门机房出入申请退回");
            // 添加审批意见
            if (StringUtils.isNotBlank(data.getOpinionText())) {
                TbPamGeneralProcessHiTask hiTask=new TbPamGeneralProcessHiTask();
                hiTask.setExamineStatus(2);
                hiTask.setId(IdGen.snowId());
                hiTask.setUserId(UserUtils.getLoginAppUser().getUserId());
                tbPamGeneralProcessTaskService.saveHistory(generalAuditVo,hiTask);
            }
        }
        // 修改申请表节点
        tbComputerRoomAccessApply.setId(data.getId());
        if(!super.updateById(tbComputerRoomAccessApply))
            throw new Exception("修改申请表节点异常");
    }


    /**
     * @Description:综合管理部负责人审批
     * @Param:com.xhsj.user.cram.dto.ComputerRoomAccessApplyExamineDto
     * @Author: liuqinghua
     * @Date: 2021/4/20
     */
    public void computerRoomAccessApplyExamine_3(ComputerRoomAccessApplyExamineDto data) throws Exception {
        // 组装审核数据
        GeneralAuditVo generalAuditVo = new GeneralAuditVo();
        BeanUtils.copyProperties(data,generalAuditVo);
        generalAuditVo.setDataId(data.getId());
        this.fillParams(generalAuditVo);
        // 流程处理
        TbComputerRoomAccessApply tbComputerRoomAccessApply=new TbComputerRoomAccessApply();
        tbPamGeneralProcessTaskService.handleComputerRoomAccessApplyExamine_3(generalAuditVo);

        // 退回-申请人
        if(data.getStatus()==1){
            tbComputerRoomAccessApply.setNodeId(new Long(-1));
            tbComputerRoomAccessApply.setNodeName("机房进出申请");
        }else{
            // 通过-抄送总经理到完结
            tbComputerRoomAccessApply.setNodeId(new Long(4));
            tbComputerRoomAccessApply.setNodeName("完结");
        }
      // 修改申请表节点
        tbComputerRoomAccessApply.setId(data.getId());
        if(!super.updateById(tbComputerRoomAccessApply))
        throw new Exception("修改申请表节点异常");

    }

    /**
     * 查询已审核数据
     * @author 苏小林
     * @date 2021/4/20 14:02
     * @param: baseParam
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.cram.vo.FindComputerRoomAccessHiTaskVo>
     */
    public IPage<FindComputerRoomAccessHiTaskVo> findComputerRoomAccessHiTask(BaseParam baseParam) throws Exception {
        // 查询历史任务列表
        GeneralAuditVo generalAuditVo = new GeneralAuditVo();
        generalAuditVo.setPage(baseParam.getPage());
        generalAuditVo.setSize(baseParam.getSize());
        generalAuditVo.setUserIds(Arrays.asList(UserUtils.getLoginAppUser().getUserId()));
        this.fillParams(generalAuditVo);
        IPage<GeneralHiTaskVo> iPage = tbPamGeneralProcessTaskService.findHiTask(generalAuditVo);
        List<GeneralHiTaskVo> hiTask = iPage.getRecords();

        if (hiTask != null && hiTask.size() > 0) {
            List<Long> dataIds = hiTask.stream().map(generalHiTaskVo -> generalHiTaskVo.getDataId()).collect(Collectors.toList());
            List<FindComputerRoomAccessHiTaskVo> list = dao.findHiTaskByDataIds(dataIds);
            for (FindComputerRoomAccessHiTaskVo findHiTaskVo : list) {
                for (GeneralHiTaskVo generalHiTaskVo : hiTask) {
                    if (findHiTaskVo.getDataId().equals(generalHiTaskVo.getDataId())) {
                        findHiTaskVo.setExamineStatus(generalHiTaskVo.getExamineStatus());
                        break;
                    }
                }
            }
            IPage<FindComputerRoomAccessHiTaskVo> resultPage = new Page<>();
            resultPage.setRecords(list);
            resultPage.setPages(iPage.getPages());
            resultPage.setTotal(iPage.getTotal());
            return resultPage;
        }

        IPage<FindComputerRoomAccessHiTaskVo> resultPage = new Page<>();
        return resultPage;
    }

    /**
     * @Description:  流程列表
     * @Param:  dataId业务id nodeId当前节点id
     * @Author: liuqinghua
     * @Date: 2021/4/20
     */
    public List<ProcessNodeVo> findComputerRoomAccessProcessList(String dataId) {
       return tbPamGeneralNodeMapper.getNodeListByProcessType("in_out_apply");
    }

    /**
     * @Description:  流程历史列表
     * @Param:BaseParam
     * @Author: liuqinghua
     * @Date: 2021/4/20
     */
    public IPage<GeneralAuditHistoryVo> findComputerRoomAccessHiProcessList(Long dataId, int page, int size) throws Exception {
                GeneralAuditVo generalAuditVo = new GeneralAuditVo();
                generalAuditVo.setPage(page);
                generalAuditVo.setSize(size);
                generalAuditVo.setDataId(dataId);
                this.fillParams(generalAuditVo);
                IPage<GeneralAuditHistoryVo> iPage = tbPamGeneralProcessTaskService.findAuditHistory(generalAuditVo);
                return iPage;
            }


    /**
     * @Description:  出入记录列表
     * @Param:BaseParam
     * @Author: liuqinghua
     * @Date: 2021/4/21
     */
    public IPage<FindComputerRoomAccessRunTaskVo> findEntryOutRecordList(BaseParamDto data) {
        Page<FindComputerRoomAccessRunTaskVo> page=new Page(data.getPage(),data.getSize());
        return dao.findEntryOutRecordList(page,data);
    }
}
